package log

import (
	"fmt"
	"github.com/siddontang/go-log/log"
	"os"
)

var logger = NewDefault(newStdHandler())

// SetDefaultLogger changes the global logger
func SetDefaultLogger(l *Logger) {
	logger = l
}

// SetLevel changes the logger level
func SetLevel(level Level) {
	logger.SetLevel(level)
}

// SetLevelByName changes the logger level by name
func SetLevelByName(name string) {
	logger.SetLevelByName(name)
}

// Fatal records the log with fatal level and exits
func Fatal(args ...interface{}) {
	logger.Output(2, LevelFatal, fmt.Sprint(args...))
	os.Exit(1)
}

// Fatalf records the log with fatal level and exits
func Fatalf(format string, args ...interface{}) {
	logger.Output(2, LevelFatal, fmt.Sprintf(format, args...))
	os.Exit(1)
}

// FatalLn records the log with fatal level and exits
func FatalLn(args ...interface{}) {
	logger.Output(2, LevelFatal, fmt.Sprintln(args...))
	os.Exit(1)
}

// Panic records the log with fatal level and panics
func Panic(args ...interface{}) {
	msg := fmt.Sprint(args...)
	logger.Output(2, LevelError, msg)
	panic(msg)
}

// PanicF records the log with fatal level and panics
func PanicF(format string, args ...interface{}) {
	msg := fmt.Sprintf(format, args...)
	logger.Output(2, LevelError, msg)
	panic(msg)
}

// PanicLn records the log with fatal level and panics
func PanicLn(args ...interface{}) {
	msg := fmt.Sprintln(args...)
	logger.Output(2, LevelError, msg)
	panic(msg)
}

// Print records the log with trace level
func Print(args ...interface{}) {
	logger.Output(2, LevelTrace, fmt.Sprint(args...))
}

// Printf records the log with trace level
func Printf(format string, args ...interface{}) {
	logger.Output(2, LevelTrace, fmt.Sprintf(format, args...))
}

// Println records the log with trace level
func Println(args ...interface{}) {
	logger.Output(2, LevelTrace, fmt.Sprintln(args...))
}

// Debug records the log with debug level
func Debug(args ...interface{}) {
	logger.Output(2, LevelDebug, fmt.Sprint(args...))
}

// DebugF records the log with debug level
func DebugF(format string, args ...interface{}) {
	logger.Output(2, LevelDebug, fmt.Sprintf(format, args...))
}

// DebugLn records the log with debug level
func DebugLn(args ...interface{}) {
	logger.Output(2, LevelDebug, fmt.Sprintln(args...))
}

// Error records the log with error level
func Error(args ...interface{}) {
	logger.Output(2, LevelError, fmt.Sprint(args...))
}

// Errorf records the log with error level
func Errorf(format string, args ...interface{}) {
	logger.Output(2, LevelError, fmt.Sprintf(format, args...))
}

// ErrorLn records the log with error level
func ErrorLn(args ...interface{}) {
	logger.Output(2, LevelError, fmt.Sprintln(args...))
}

// Info records the log with info level
func Info(args ...interface{}) {
	logger.Output(2, LevelInfo, fmt.Sprint(args...))
}

// InfoF records the log with info level
func InfoF(format string, args ...interface{}) {
	logger.Output(2, LevelInfo, fmt.Sprintf(format, args...))
}

// InfoLn records the log with info level
func InfoLn(args ...interface{}) {
	logger.Output(2, LevelInfo, fmt.Sprintln(args...))
}

// Warn records the log with warn level
func Warn(args ...interface{}) {
	logger.Output(2, LevelWarn, fmt.Sprint(args...))
}

// WarnF records the log with warn level
func WarnF(format string, args ...interface{}) {
	logger.Output(2, LevelWarn, fmt.Sprintf(format, args...))
}

// WarnLn records the log with warn level
func WarnLn(args ...interface{}) {
	logger.Output(2, LevelWarn, fmt.Sprintln(args...))
}

func NewLog(logfile, logLevel string) (res *Logger, err error) {
	var fileHandler *FileHandler
	var streamHandler *StreamHandler
	if fileHandler, err = NewFileHandler(logfile, os.O_RDWR|os.O_APPEND|os.O_CREATE); err != nil {
		return
	}
	if streamHandler, err = NewStreamHandler(fileHandler); err != nil {
		return
	}
	res = NewDefault(streamHandler)
	res.SetLevelByName(logLevel)
	return
}
func CreateLogger(logfile []string, logLevel string) (err error) {
	for k,v := range logfile{
		var point *Logger
		if point, err = NewLog(v, logLevel); err != nil {
			return
		}
		switch k {
		case 0:
			mainLogF = point
		case 1:
			scheduleLogF = point
		case 2:
			monitorLogF = point
		case 3:
			sendMsgLogF = point
		case 4:
			errorLogF = point
		}
	}
	return
}
var (
	mainLogF     *Logger
	scheduleLogF *Logger
	sendMsgLogF    *Logger
	monitorLogF  *Logger
	errorLogF    *Logger
)

func Stdout() *Logger {
	std, _ := log.NewStreamHandler(os.Stdout)
	return NewDefault(std)
}
func MainLog() *Logger {
	if mainLogF == nil {
		mainLogF = Stdout()
	}
	return mainLogF
}
func ScheduleLog() *Logger {
	if scheduleLogF == nil {
		scheduleLogF = Stdout()
	}
	return scheduleLogF
}
func SendMsg() *Logger {
	if sendMsgLogF == nil {
		sendMsgLogF = Stdout()
	}
	return sendMsgLogF
}
func MonitorLog() *Logger {
	if monitorLogF == nil {
		monitorLogF = Stdout()
	}
	return monitorLogF
}
func ErrorLog() *Logger {
	if errorLogF == nil {
		errorLogF = Stdout()
	}
	return errorLogF
}